<?php

ini_set('display_errors', 'on');
error_reporting(E_ALL ^ E_NOTICE);

/**
 * Clix Framework Advanced Example
 * 
 * @author: Petr Kratina <petr.kratina@gmail.com>
 */  

require_once '../../Clix.php';

class Wiki extends Clix
{
    public function init()
    {
        parent::init();

        session_start();
        
        $this->view->admin = ($_SESSION['password'] == $this->config['wiki']['password']);

        $this->view->menu = $this->getBody('special:menu', true);
        $this->view->header = $this->getBody('special:header');
        $this->view->footer = $this->getBody('special:footer', true);
    }

    public function parseWikiText($text, $special = false)
    {
        $rules = array();
        $replaces = array();
        
        $text = htmlspecialchars($text);
        
        // bold text
        $rules[] = "/\*([^*\r\n]+)\*/";
        $replaces[] = '<b>${1}</b>';

        /*
        // external links
        $rules[] = "/(http[s]?:\/\/[^ \n\r\t\s<]+)/";
        $replaces[] = '<a href="${1}">${1}</a>';
        */

        // emails
        $rules[] = "/([^ @\n\r\t\s>]+[@][^ @\n\r\t\s<]+)/";
        $replaces[] = '<a href="mailto:${1}">${1}</a>';
        
        // headings
        $rules[] = "/((^)|(\n))={3}([^=\r\n]+)={3}/";
        $replaces[] = '</p><h3>${4}</h3><p>';
        $rules[] = "/((^)|(\n))={2}([^=\r\n]+)={2}/";
        $replaces[] = '</p><h2>${4}</h2><p>';
        $rules[] = "/((^)|(\n))=([^=\r\n]+)=/";
        $replaces[] = '</p><h1>${4}</h1><p>';

        // bullets
        $rules[] = "/((^)|(\n))\*([^\r\n]+)/";
        $replaces[] = '<li>${4}</li>';

        // links
        $rules[] = "/\[\[([^\|\]]+)\|([^\]]+)\]\]/";
        $replaces[] = '<a href="./${1}">${2}</a>';
        $rules[] = "/\[\[([^\]\|]+)\]\]/";
        $replaces[] = '<a href="./${1}">${1}</a>';

        // external links
        $rules[] = "/\[([^ \]]+) ([^\]]+)\]/";
        $replaces[] = '<a href="${1}">${2}</a>';

        // paragraphs / new lines
        if (!$special) {
            $rules[] = "/([\r]?[\n]){2}/";
            $replaces[] = "\n</p>\n<p>\n";
        }
        
        // apply rules
        $text = preg_replace($rules, $replaces, $text);

        if (!$special) {
            $text = '<p>' . $text . '</p>';
        }
        
        // clear empty paragraphs
        $text = preg_replace("/<p>\s*<\/p>/", '', $text);
        
        return $text;
    }
    
    public function getPage($title)
    {
        $sql = "SELECT * FROM pages WHERE title LIKE {$this->db->quote($title)}";
        return $this->db->fetchRow($sql);
    }
    
    public function isLocked($title)
    {
        $sql = "SELECT locked FROM pages WHERE title LIKE {$this->db->quote($title)}";
        if ($this->db->fetchOne($sql)==1) {
            return true;
        }
        return false;
    }
    
    public function getBody($title, $special = false)
    {
        if ($data=$this->getPage($title)) {
            return $this->parseWikiText($data['body'], $special);
        }
        return false;
    }
    
    public function indexAction()
    {
        $sql = "SELECT title FROM pages ORDER BY id ASC LIMIT 1";
        $title = $this->db->fetchOne($sql);
        header("Location: {$this->config['clix']['base']}/{$title}");
        exit;
    }

    public function defaultAction()
    {
        $title = iconv('windows-1250', 'UTF-8', $this->_getParam(0, true));
        $this->view->title = $title;
        
        if ($_SESSION['password']==$this->config['wiki']['password']) {
            $this->view->edit = $title;
        }
        
        if ($data = $this->getPage($title)) {
            $this->view->body = $this->parseWikiText($data['body']);
            $this->view->locked = $data['locked'];
        } elseif ($this->view->admin) {
            $this->_redirect("/edit/$title");
        } 
    }
    
    public function editAction()
    {
        $title = iconv('windows-1250', 'UTF-8', $this->_getParam(1, true));
        $this->view->title = $title;
        $this->view->return = $title;

        if ($_SESSION['password']!=$this->config['wiki']['password']) {
            $this->_redirect("/{$title}");
        }
        
        if ($this->isLocked($title)) {
            die('locked');
        }

        if (!empty($_POST)) {
            $id = intval($_POST['id']);
            $title = strip_tags($_POST['title']);
            $body = $_POST['body'];
            if ($id>0) {
                $sql = "UPDATE pages
                           SET title = {$this->db->quote($title)},
                               body = {$this->db->quote($body)}
                         WHERE id = $id";
            } else {
                $sql = "REPLACE INTO pages
                                     (`title`, `body`)
                              VALUES ({$this->db->quote($title)}, {$this->db->quote($body)})";
            }
            $this->db->query($sql);
            $this->_redirect("/{$title}");
        }

        $data = $this->getPage($title);
        $this->view->body = $data['body'];
        $this->view->id = intval($data['id']); 
    }
    
    public function resetAction()
    {
        if ($_POST['sure']=='true') {
            $sql = file_get_contents('./pages.sql');
            $sql = explode("\r\n", $sql);
            $this->db->query("TRUNCATE TABLE pages");
            foreach ($sql as $q) {
                if (!empty($q)) {
                    $this->db->query($q);
                }
            }
            $this->_redirect("/");
        }
    }
    
    public function logoutAction()
    {
        $_SESSION['password'] = '';
        $this->_redirect("/");
    }
    
    public function loginAction()
    {
        if ((!empty($_POST['password']))and($_POST['password']==$this->config['wiki']['password'])) {
            $_SESSION['password'] = $_POST['password'];
            $this->_redirect("/");
        }
    }
}

new Wiki('app.ini');
